﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using blackhouse.BlackApart.Data;
using System.Diagnostics;
using System.Globalization;
using blackhouse.BlackApart.Business.Furnitures;

namespace blackhouse.BlackApart.Business.Apartments {

    [DebuggerDisplay("{Name} ({Id})")]
    public class DaApartmentGroup : IApartmentGroup {

        #region Fields

        private ImpApartmentGroup instance;
        private IApartmentGroupDataAccess dataAccess;
        private int defaultLocationId;

        #endregion

        #region Constructors

        public DaApartmentGroup(IApartmentGroupDataAccess iDataApartmentGroup) {
            this.dataAccess = iDataApartmentGroup;
            this.instance = new ImpApartmentGroup();
        }

        public DaApartmentGroup(IApartmentGroupDataAccess iApartmentGroupDataAccess, int groupId) {
            this.dataAccess = iApartmentGroupDataAccess;
            this.instance = this.ConvertToInstance(this.dataAccess.GetApartmentGroup(groupId, CultureInfo.CurrentCulture.Name));
            if (this.instance == null)
                this.instance = new ImpApartmentGroup();
        }

        public DaApartmentGroup(IApartmentGroupDataAccess iApartmentGroupDataAccess, ApartmentGroupData data) {
            this.dataAccess = iApartmentGroupDataAccess;
            this.instance = this.ConvertToInstance(data);
            if (this.instance == null)
                this.instance = new ImpApartmentGroup();
        }

        #endregion

        #region Properties

        public int Id {
            get { return this.instance.Id; }
            private set { this.instance.Id = value; }
        }

        public string Name {
            get { return this.instance.Name; }
            set { this.instance.Name = value; }
        }

        public string ShortName {
            get { return this.instance.ShortName; }
            set { this.instance.ShortName = value; }
        }

        public int NumberOfPeople {
            get { return this.instance.NumberOfPeople; }
            set { this.instance.NumberOfPeople = value; }
        }

        public IApartmentLocation DefaultLocalization {
            get {
                if (this.instance.DefaultLocalization.Id == 0 && this.defaultLocationId > 0) // późne wiązanie, lokalizacja jest pobierana tylko wtedy, gdy jest potrzebna
                    this.instance.DefaultLocalization = Factory.Instance().GetApartmentLocation(this.defaultLocationId);
                return this.instance.DefaultLocalization;
            }
            set { this.instance.DefaultLocalization = value; }
        }

        public float AreaSize {
            get { return this.instance.AreaSize; }
            set { this.instance.AreaSize = value; }
        }

        public double Popularity {
            get { return this.instance.Popularity; }
            set { this.instance.Popularity = value; }
        }

        public float Stars {
            get { return this.instance.Stars; }
            set { this.instance.Stars = value; }
        }

        public IApartmentPhoto MainPhoto {
            get { return this.instance.MainPhoto; }
            set { this.instance.MainPhoto = value; }
        }

        public DateTime LastMod {
            get { return this.instance.LastMod; }
            set { this.instance.LastMod = value; }
        }

        public ApartmentOptionField[] Fields {
            get {
                if (this.instance.Fields == null)
                    this.instance.Fields = this.dataAccess.GetApartmentGroupOptionFields(this.Id, CultureInfo.CurrentCulture.Name).Select(of => new ApartmentOptionField(of)).OrderBy(ao => ao.Title).ToArray();
                return this.instance.Fields;
            }
            set {
                this.instance.Fields = value;
            }
        }

        public string LidDescription {
            get { return this.instance.LidDescription; }
            private set { this.instance.LidDescription = value; }
        }

        public string Description {
            get {
                return this.GetProperty("opis").ToString();
            }
        }

        public string Url {
            get { return this.instance.Url; }
            set { this.instance.Url = value; }
        }

        public Guid Guid {
            get { return this.instance.Guid; }
            set { this.instance.Guid = value; }
        }

        #endregion

        #region Methods

        public bool Save() {
            if (!this.instance.Save()) return false;
            if (!this.DefaultLocalization.Save()) return false;
            int id = this.dataAccess.SaveApartmentGroup(this.Id, this.Name, this.NumberOfPeople, this.DefaultLocalization.Id, this.AreaSize);
            if (id > 0)
                this.instance.Id = id;
            return id > 0;
        }

        public bool Delete() {
            int id = this.Id;
            if (!this.instance.Delete()) return false;
            int affectedRow = this.dataAccess.DeleteApartmentGroup(id);
            return affectedRow > 0;
        }

        public bool Exists() {
            return
                this.instance.Exists()
                && this.dataAccess.CheckExists(this.Id);
        }

        private ImpApartmentGroup ConvertToInstance(ApartmentGroupData data) {
            if (data.Id > 0) {
                ImpApartmentGroup group = new ImpApartmentGroup();
                group.AreaSize = data.AreaSize;
                this.defaultLocationId = data.DefaultLocationId;
                //group.DefaultLocalization = Factory.Instance().GetApartmentLocation(data.DefaultLocationId);
                group.Id = data.Id;
                group.Name = data.Name;
                group.ShortName = data.ShortName;
                group.NumberOfPeople = data.NumberOfPeople;
                group.Popularity = data.Popularity;
                group.Stars = data.Stars;
                group.MainPhoto = Factory.Instance().GetApartmentPhoto();
                if (group.MainPhoto is DaApartmentPhoto)
                    ((DaApartmentPhoto)group.MainPhoto).Read(data.MainPhoto);
                group.LastMod = data.LastMod;
                return group;
            }
            else
                return null;
        }

        public IApartment MakeDefaultApartment() {
            return this.instance.MakeDefaultApartment();
        }

        public IApartment[] GetApartments() {
            return this.instance.GetApartments();
        }

        public IApartmentGroup[] GetAllApartmentTypes() {
            return
                this.dataAccess.GetApartmentGroups(CultureInfo.CurrentCulture.Name).Select(gd => new DaApartmentGroup(dataAccess, gd)).ToArray();
        }

        public object GetProperty(string propertyKey) {
            if (this.instance.ExtraProperties == null) {
                this.instance.ExtraProperties = this.dataAccess.GetApartmentGroupProperties(this.Id, CultureInfo.CurrentCulture.Name);
            }
            return this.instance.GetProperty(propertyKey);
        }

        public Dictionary<string, string> GetArrayProperty(string propertyKey) {
            return this.dataAccess.GetApartmentGroupArrayProperties(this.Id, propertyKey, CultureInfo.CurrentCulture.Name);
        }

        public Seo GetSeo() {
            if (this.instance.Seo == null) {
                SeoData data = this.dataAccess.GetApartmentGroupSeo(this.Id, CultureInfo.CurrentCulture.Name);
                Seo seo = new Seo();
                seo.PageTitle = data.PageTitle;
                if (string.IsNullOrEmpty(seo.PageTitle))
                    seo.PageTitle = this.Name;
                seo.PageKeywords = data.PageKeywords;
                seo.PageDescription = data.PageDescription;
                this.instance.Seo = seo;
            }
            return this.instance.GetSeo();
        }

        public IApartmentPhoto[] GetAllPhotos() {
            return this.instance.GetAllPhotos();
        }

        public IFurniture[] GetFurnitures() {
            return this.instance.GetFurnitures();
        }

        #endregion

        #region Equals Methods

        public override bool Equals(object obj) {
            return this.instance.Equals(obj);
        }

        public override int GetHashCode() {
            return this.instance.GetHashCode();
        }

        public override string ToString() {
            return this.instance.ToString();
        }

        #endregion

    }
}
